package com.rchat.pocmini.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ljd on 2017/3/16.
 */

public abstract class BaseDaoImpl implements BaseDao {

    private static final String TAG = "BaseDaoImpl";
    protected Context mContext;
    protected SQLiteDatabase mDB;

    public BaseDaoImpl() {
    }

    /**
     * 打开数据库
     *
     * @return
     */
    @Override
    public boolean openDB() {
        try {
            if (mDB == null) {
                if (getDbHelper() != null) {
                    mDB = getDbHelper().getWritableDatabase();
                    return true;
                } else {
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            closeDB();
        }
        return false;
    }

    @Override
    public void closeDB() {
        if (mDB != null) {
            mDB.close();
            mDB = null;
        }
    }

    /**
     * 数据库发生异常则重新打开
     *
     * @param e
     */
    public void useDbWhenCatchThrowable(Throwable e) {
        openDB();
    }

    /**
     * 插入数据
     *
     * @param table
     * @param valuesMap
     * @return
     */
    public long insertData(String table, Map<String, String> valuesMap) {
        if (valuesMap.isEmpty()) {
            return 0;
        }

        ContentValues values = new ContentValues();
        for (Map.Entry<String, String> entry : valuesMap.entrySet()) {
            values.put(entry.getKey(), entry.getValue());
        }
        return insertData(table, values);
    }

    public long insertData(String table, ContentValues values) {
        if (values == null) {
            return 0;
        }
        try {
            return mDB.insert(table, null, values);
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
            return -1;
        }
    }


    public void batchReplaceDbData(String table, ArrayList<ContentValues> valuesList) {
        if (valuesList == null || valuesList.size() == 0) {
            return;
        }

        mDB.beginTransaction();
        try {
            for (ContentValues values : valuesList) {
                mDB.replace(table, null, values);
            }
            mDB.setTransactionSuccessful();
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
        } finally {
            mDB.endTransaction();
        }
    }

    /**
     * 以主键做为标识，如果数据存在则替换，不存在则插入
     *
     * @param table
     * @param valuesMap
     * @return
     */
    public long replaceDbData(String table, Map<String, String> valuesMap) {
        if (valuesMap.isEmpty()) {
            return 0;
        }

        ContentValues values = new ContentValues();
        for (Map.Entry<String, String> entry : valuesMap.entrySet()) {
            values.put(entry.getKey(), entry.getValue());
        }
        return replaceDbData(table, values);
    }

    public long replaceDbData(String table, ContentValues values) {
        try {
            return mDB.replace(table, null, values);
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
            return -1;
        }
    }

    /**
     * 更新数据
     *
     * @param table
     * @param valuesMap
     * @param whereClause
     * @param whereArgs
     * @return
     */
    public long updateDbData(String table, Map<String, String> valuesMap, String whereClause, String[] whereArgs) {
        if (valuesMap.isEmpty()) {
            return 0;
        }

        ContentValues values = new ContentValues();
        for (Map.Entry<String, String> entry : valuesMap.entrySet()) {
            values.put(entry.getKey(), entry.getValue());
        }
        return updateDbData(table, values, whereClause, whereArgs);
    }

    public long updateDbData(String table, ContentValues values, String whereClause, String[] whereArgs) {
        try {
            return mDB.update(table, values, whereClause, whereArgs);
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
            return -1;
        }
    }

    /**
     * 查询数据
     *
     * @param sql
     * @param paramse
     * @return
     */
    public List<Map<String, String>> cursorToList(String sql, String[] paramse) {
        List<Map<String, String>> resList = new ArrayList<Map<String, String>>();

        Cursor cursor = null;
        try {
            cursor = mDB.rawQuery(sql, paramse);
            String[] columnNames = cursor.getColumnNames();
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    Map<String, String> m = new HashMap<String, String>();
                    for (int i = 0; i < columnNames.length; i++) {
                        String value = cursor.getString(i);
                        m.put(columnNames[i], value);
                    }
                    resList.add(m);
                }
            }
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
        } finally {
            if (cursor != null) {
                cursor.close();
                cursor = null;
            }
        }

        return resList;
    }

    /**
     * 根据指定条件删除数据
     *
     * @param table
     * @param whereClause
     * @param whereArgs
     * @return
     */
    public long deleteDbData(String table, String whereClause, String[] whereArgs) {
        try {
            return mDB.delete(table, whereClause, whereArgs);
        } catch (Exception e) {
            useDbWhenCatchThrowable(e);
            return -1;
        }
    }

    /**
     * 删除表中的所有数据
     *
     * @param tableName
     * @author Tan
     * @Date 2015-1-19  下午3:54:36
     */
    public void clearDbData(String tableName) {
        String sql = "DELETE FROM " + tableName;
        mDB.execSQL(sql);
    }

    /**
     * 获取数据库句柄
     *
     * @return
     */
    protected abstract SQLiteOpenHelper getDbHelper();
}
